Un-strip ui-text-android and ui-unit-android Compose bindings#1440
Conversation
Co-authored-by: jonathanpeppers <840039+jonathanpeppers@users.noreply.github.com>
|
@copilot build errors: |
There was a problem hiding this comment.
Pull request overview
This PR updates the androidx.compose.ui binding customizations so the ui-text-android and ui-unit-android NuGets ship real C#-consumable APIs (instead of being fully stripped), aligning them with the prior ui-graphics-android un-stripping work.
Changes:
- Stop stripping all packages in
ui-text-androidandui-unit-android, and apply consistentAndroidX.Compose.UI.*managed namespace casing viamanagedNamemetadata. - Add targeted metadata fixes to unblock binding generation (remove problematic interface implementations, rename signature-colliding overloads, and remove members that reference unbound/internal types).
- Update packaging surface area and versioning (
AndroidXProject.cshtml,published-namespaces.txt,PublicAPI.Unshipped.txt, andconfig.jsonNuGet revision bumps).
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| source/AndroidXProject.cshtml | Marks the Compose UI Text/Unit packages as “with bindings” to suppress the “no C# bindings” note. |
| source/androidx.compose.ui/ui-unit-android/Transforms/Metadata.xml | Un-strips the unit Android artifact, enforces UI casing, and resolves binding collisions via metadata adjustments. |
| source/androidx.compose.ui/ui-unit-android/PublicAPI/PublicAPI.Unshipped.txt | Regenerated API surface reflecting newly exposed unit bindings. |
| source/androidx.compose.ui/ui-text-android/Transforms/Metadata.xml | Un-strips the text Android artifact, enforces UI casing, and removes/renames members to avoid generator/interface issues. |
| source/androidx.compose.ui/ui-text-android/PublicAPI/PublicAPI.Unshipped.txt | Regenerated API surface reflecting newly exposed text bindings. |
| published-namespaces.txt | Adds newly exposed AndroidX.Compose.UI.Text.* and AndroidX.Compose.UI.Unit.* namespaces. |
| config.json | Bumps NuGet revision (1.11.2 → 1.11.2.1) for the affected Compose UI Text/Unit artifacts. |
Co-authored-by: jonathanpeppers <840039+jonathanpeppers@users.noreply.github.com>
Fixed in 1659cd0's follow-up commit. The blocking The remaining |
Closes #58 (the bulk of it — see _Deferred_ at the bottom for the remainder). ## What ships ### New `Text` properties `Color`, `FontStyle`, `FontFamily`, `Align`, `Overflow`, `SoftWrap`, `MaxLines`, `MinLines`. ```csharp new Text("Italic serif red, centered") { Color = ColorKt.Color(0xC6, 0x28, 0x28, 0xFF), FontStyle = FontStyle.Italic, FontFamily = FontFamily.Serif, Align = TextAlign.Center, Modifier = Modifier.Companion.FillMaxWidth(), } new Text("This long line clips with an ellipsis…") { MaxLines = 1, Overflow = TextOverflow.Ellipsis, SoftWrap = false, } ``` ### New `TextField` / `OutlinedTextField` slots `Enabled`, `ReadOnly`, `Label`, `Placeholder`, `LeadingIcon`, `TrailingIcon`, `Prefix`, `Suffix`, `SupportingText`, `IsError`, `SingleLine`, `MaxLines`, `MinLines`. ```csharp new TextField(name) { Label = new Text("Your name"), Placeholder = new Text("Type something…"), LeadingIcon = new Text("👤"), TrailingIcon = new Text("✎"), SupportingText = new Text("Powered by issue #58 slots"), SingleLine = true, } ``` ## Generator changes `ComposeBridgeGenerator` and `ComposeFacadeGenerator` now recognize **nullable primitives** (`bool?`, `int?`, `long?`, `float?`, `double?`). At the bridge level these lower to `(name ?? defaultLiteral)` so a `null` clears the corresponding `$default` bit and Kotlin's default runs; at the facade level they surface as nullable auto-properties — parity with existing nullable Compose value types like `Dp?` / `Sp?`. Three tests cover the new behaviour (one bridge, one facade, one mixed). ## New wrapper types | Type | Lowering | Why | |------|----------|-----| | `FontStyle` | reference (slot `L`) | `@JvmInline value class` but Compose declares `fontStyle:` nullable, which boxes | | `FontFamily` | reference (slot `L`) | regular Kotlin class, just not bound yet | | `TextOverflow` | packed `int` (slot `I`) | `@JvmInline value class`, declared **non-nullable** in Compose | | `TextAlign` | reference (slot `L`) — **breaking change**, was a value struct | same boxing reason as `FontStyle` | `FontStyle` and `TextAlign` reach Compose's companion via the mangled inline-class accessors (`getCenter-e0LSkKk()I`, `getNormal-_-LCdwA()I`) and box through the synthesized `box-impl(I)L<Type>;` static. `FontFamily`'s companion getters return concrete subtypes (`SystemFontFamily` / `GenericFontFamily`) so each call uses its exact descriptor. All names verified against `ui-text-android` 1.11.2.1 bytecode. ## Sample The Greeting tab in `MainActivity.cs` now demos the new styling — color + italic serif center-aligned text, monospace end-aligned text, ellipsis clipping with `MaxLines = 1`, two-line clamp with reserved height, plus a `TextField` and `OutlinedTextField` exercising the new slots. ## Verification - `dotnet test src/ComposeNet.SourceGenerators.Tests` — **83/83 passing** - `dotnet build src/ComposeNet.Compose` — clean (`PublicAPI.Unshipped.txt` updated) - `dotnet build src/ComposeNet.Sample` — clean ## Deferred (blocked or out of scope) - **`KeyboardOptions` / `KeyboardActions`** — `KeyboardOptions` ctor is stripped from the binding (inline-class params: `KeyboardType`, `ImeAction`, `KeyboardCapitalization`); needs a `[ComposeBridge(JvmName="<init>")]` follow-up. - **`VisualTransformation`, `AnnotatedString`, `TextStyle`, `LinkAnnotation`** — all in `androidx.compose.ui.text.input` / `androidx.compose.ui.text`, still 0 exported types until the next Compose package release post [dotnet/android-libraries#1440](dotnet/android-libraries#1440) (merged but not yet shipped). - **`BasicText` / `BasicTextField` / `LocalTextStyle` / `FocusRequester`** — separate facades; out of scope here. ## Breaking change `TextAlign` is no longer a `record struct`. Callers that previously used the `Pack` static, `Equals`/`Deconstruct`, or accessed `Value` directly will need to migrate; the `TextAlign.Left/Right/Center/Justify/Start/End/Unspecified` accessors are unchanged in name and still typed `TextAlign`. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Mirrors #1438 (which un-stripped
ui-graphics-android) for the remaining Compose styling packages.ui-text-androidandui-unit-androidpreviously shipped with<remove-node path="/api/package" />and exported zero public types, forcing managed callers to hand-roll JNI lookups forFontWeight.Bold,Dp.Hairline,TextUnit.Unspecified, etc.Metadata transforms
ui-text-android/Transforms/Metadata.xml— drop the package strip; addUI-casedmanagedNamefor everyandroidx.compose.ui.text.*package. Binding fixes: dropComparableonFontWeight; dropCollection/List/CharSequence/AppendableonLocaleList/FontListFontFamily/AnnotatedString/AnnotatedString.Builder; rename the collidingappend(String)overload; remove two members leaking the package-privatePlatformLocaleDelegateand an unreferencedkotlinx.coroutines.CoroutineDispatcher.ui-unit-android/Transforms/Metadata.xml— drop the strip; addUI-casedmanagedName; dropComparableonDp; rename inline-class operator/extension overloads that lower to identical primitive signatures (Div2/Constrain2/Minus2/Plus2/IntRect2/Lerp2/IsSpecified2/IsUnspecified2/TakeOrElse2).Inline value-class types still surface as raw primitives at JNI (e.g.
Dp→float), consistent with the #1438 lowering policy; their companions and constants now bind.Packaging / surface
AndroidXProject.cshtml— addXamarin.AndroidX.Compose.UI.Text(.Android)and…UI.Unit(.Android)toComposePackagesWithBindings(suppresses the "C# bindings are not provided" note).published-namespaces.txt— add the 13 newly-exposed namespaces.PublicAPI.Unshipped.txt— regenerated for both packages.config.json— bumpnugetVersion1.11.2→1.11.2.1for ui-text, ui-text-android, ui-unit, ui-unit-android.This exposes real C# classes such as
AndroidX.Compose.UI.Text.Font.FontWeight,…Text.Style.TextDecoration,…Text.TextStyle,…Unit.Dp.Companion, and…Unit.TextUnit.Companion.foundation-layout-android collisions
Once
Dpbecomes resolvable,foundation-layout-androidsurfaces new Dp-based inline-class method collisions (CS0111) — anticipated in the issue's foundation note. These are now fixed:foundation-layout-android/Transforms/Metadata.xml— addmanagedNamerenames for the mangled inline value-class overloads that lower to the same primitive signature as their un-mangled siblings:FlexConfigScope.basis-0680j_4→Basis2;GridConfigurationScope.column-0680j_4/column-XZblgos→Column2/Column3androw-0680j_4/row-XZblgos→Row2/Row3; plus the matchingResolvedFlexItemInfo.basis-0680j_4→Basis2on the public implementing class.GridConfigurationScopeImplis package-private, so it isn't bound and needs no transform. This mirrors the inline-class rename approach inui-unit-android.